/**
 * Copyright (c) 2010-2011 Pierre Labatut
 *
 * This file is part of Space-Chronicles project.
 *
 * Space-Chronicles is free software: you can redistribute it and/or modify it
 * under the terms of its license which may be found in the accompanying
 * LICENSE file or <http://code.google.com/p/space-chronicles/>.
 */
package space.game.world;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.List;
import javax.media.opengl.GL;
import javax.media.opengl.GL3;
import javax.media.opengl.GL3bc;
import jinngine.math.Matrix4;
import jinngine.math.Vector3;
import space.gl.Attribute;
import space.gl.Program;
import space.gl.RenderContext;

/**
 *
 * @author Pierre Labatut
 */
public class Trail {
    //POsition of the engine nozzle in object local coordinate

    private final Vector3 nozzle;
    private final List<Vector3> points = new ArrayList<Vector3>();

    public Trail(final Vector3 pointInParentObjectCoord) {
        nozzle = new Vector3(pointInParentObjectCoord);
    }

    public void addTrailPoint(Matrix4 objectToWorld) {
        points.add(objectToWorld.multiply(nozzle));
    }

    public void overwriteTrailPoint(final Matrix4 objectToWorld) {
        final Vector3 last = points.get(points.size() - 1);
        Matrix4.multiply(objectToWorld, nozzle, last);
    }

    public void draw(RenderContext rc, Program trailShader) {
        // rc.setObjectWorld(Matrix4.identity());

        final GL3bc gl = rc.gl();
        gl.glDisable(GL.GL_CULL_FACE);
        rc.stopUsingProgram();
        rc.setProgram(trailShader);
        // trailShader.startUsingProgram(gl);

        /*
        rc.applyLegacyMatrix();
        gl.glLineWidth(10);
        gl.glBegin(GL3.GL_LINE_STRIP);
        
        gl.glColor3d(1., 1., 1.);
        for (Vector3 v : points) {
        gl.glVertex3d(v.x, v.y, v.z);
        }
        gl.glEnd();*/
        rc.startUsingProgram();
        rc.applyAllUniforms();
                
        //Disable element vertex_buffer_object        
        gl.glBindBuffer(GL3.GL_ARRAY_BUFFER, 0);

        final ByteBuffer buffer = ByteBuffer.allocateDirect(
                points.size() * 3 * Float.SIZE / Byte.SIZE);
        buffer.order(ByteOrder.nativeOrder());
        final FloatBuffer fbuffer = buffer.asFloatBuffer();
        for (Vector3 v : points) {
            fbuffer.put((float) v.x);
            fbuffer.put((float) v.y);
            fbuffer.put((float) v.z);
        }
        fbuffer.rewind();

        rc.applyVertexAttribPointer(Attribute.VERTEX, 3, GL.GL_FLOAT, false, 0, buffer);
        gl.glDrawArrays(GL3bc.GL_POINTS, 0, points.size());
        rc.glDisableVertexAttribArray(Attribute.VERTEX);

        rc.startUsingProgram();
    }
}
